package global

import (
	"fmt"
	"log"
	"os"
	"runtime"
	"strings"
	"sync"
	"time"
)

// 自定义日志格式
type CustomLogger struct {
	logger   *log.Logger
	logLevel string
}

// 日志级别常量
const (
	LevelDebug   = "DEBUG"
	LevelInfo    = "INFO"
	LevelWarn    = "WARN"
	levelWarning = "WARNING"
	LevelError   = "ERROR"
	LevelSuccess = "SUCCESS"
)

// 日志级别权重
var levelWeights map[string]int = map[string]int{
	LevelDebug:   0,
	LevelInfo:    1,
	LevelWarn:    2,
	levelWarning: 2,
	LevelError:   3,
	LevelSuccess: 4,
}

var levelColors map[string]string = map[string]string{
	"DEBUG":    "\x1b[97;46m", // 蓝色
	"INFO":     "\x1b[97;42m", // 绿色
	"WARN":     "\x1b[97;43m", // 黄色
	"ERROR":    "\x1b[97;41m", // 红色
	"CRITICAL": "\x1b[97;45m", // 红色加粗
	"SUCCESS":  "\x1b[97;42m", // 绿色加粗
}

var singletonLogger *CustomLogger
var once sync.Once

func _getLogger() *CustomLogger {
	return &CustomLogger{
		logger: log.New(os.Stdout, "", 0), // 输出到标准输出，不带前缀
	}
}

// 初始化自定义日志
func NewCustomLogger() *CustomLogger {
	once.Do(func() {
		singletonLogger = _getLogger()

		// TODO: 初始化日志级别
		singletonLogger.logLevel = LevelDebug
	})

	return singletonLogger
}

// 设置日志级别
func (l *CustomLogger) SetLogLevel(level string) {
	l.logLevel = level
}

// 自定义日志格式
func (l *CustomLogger) formatLog(level string, message string) string {
	// 获取当前时间
	now := time.Now().Format("2006-01-02 15:04:05.000")

	// 获取调用栈信息
	pc, file, line, ok := runtime.Caller(3) // 跳过三层调用栈

	fileSlice := strings.Split(file, "/")
	caller := "unknown"
	if ok {
		funcName := runtime.FuncForPC(pc).Name()
		caller = fmt.Sprintf("%s:%d", fileSlice[len(fileSlice)-1], line)
		if index := strings.LastIndex(funcName, "."); index != -1 {
			caller = fmt.Sprintf("%s.[%s].%s:%d", funcName[:index], fileSlice[len(fileSlice)-1], funcName[index+1:], line)
		}
	}

	// 构建日志格式
	return fmt.Sprintf("\x1b[32m%s\x1b[0m |%s%s\x1b[0m| \x1b[35m%s\x1b[0m - \x1b[33m%s\x1b[0m",
		now, levelColors[level], level, caller, message)
}

// 日志输出函数
func (l *CustomLogger) Log(level string, message string) {
	// 判断当前日志级别是否允许输出
	if levelWeights[level] < levelWeights[l.logLevel] {
		return
	}

	logLine := l.formatLog(level, message)
	l.logger.Println(logLine)
}

// 不同级别的日志函数
func (l *CustomLogger) Info(message string) {
	l.Log("INFO", message)
}

func (l *CustomLogger) Infof(format string, v ...any) {
	message := fmt.Sprintf(format, v...)
	l.Log("INFO", message)
}

func (l *CustomLogger) Error(message string) {
	l.Log("ERROR", message)
}

func (l *CustomLogger) Errorf(format string, v ...any) {
	message := fmt.Sprintf(format, v...)
	l.Log("ERROR", message)
}

func (l *CustomLogger) Debug(message string) {
	l.Log("DEBUG", message)
}

func (l *CustomLogger) Debugf(format string, v ...any) {
	message := fmt.Sprintf(format, v...)
	l.Log("DEBUG", message)
}

func (l *CustomLogger) Warn(message string) {
	l.Log("WARN", message)
}

func (l *CustomLogger) Warnf(format string, v ...any) {
	message := fmt.Sprintf(format, v...)
	l.Log("WARN", message)
}
